// latent matrix type
#ifndef LATENT_HH_
#define LATENT_HH_
#include "util.hh"
#include <boost/unordered_map.hpp>
#include <boost/ptr_container/ptr_map.hpp>
#include <boost/assign/ptr_map_inserter.hpp>

// latent assignment matrix
struct latent_matrix_t
{
  typedef boost::unordered_map<int, double> vec_t;
  typedef boost::ptr_map<int, vec_t> mat_t;

  explicit latent_matrix_t(const size_t n) :
      n(n), mat()
  {
    init();
  }

  vec_t& operator()(size_t j)
  {
    return mat.at(j);
  }

  const vec_t& operator()(size_t j) const
  {
    return mat.at(j);
  }

  double operator()(size_t i, size_t j) const
  {
    if (mat.count(i) == 0)
      return 0.;
    const vec_t& row = mat.at(i);
    return row.count(j) > 0 ? row.at(j) : 0.;
  }

  const size_t n;
  mat_t mat;
  size_t size() const
  {
    return n;
  }
private:
  void init()
  {
    for (size_t j = 0; j < n; ++j)
      boost::assign::ptr_map_insert(mat)(j);
  }

};


#endif /* LATENT_HH_ */
